use strict;

my $ROOT = '../src';
my $PREFS_FILE = "$ROOT/defaults/preferences/prefs.js";
my $PREF_KEYS_FILE = "$ROOT/content/constants/prefKeys.js";
my $STRING_KEYS_FILE = "$ROOT/content/constants/stringKeys.js";

sub Main();
sub CheckPrefsVsXULAndJS($$ );
sub CheckXULPrefs($$ );
sub CheckJSPrefs($$$ );
sub CheckPrefKeys($$ );
sub ListPrefs($$ );
sub CheckDTDVsXUL($$ );
sub CheckEntities($$ );
sub ListEntities($$ );
sub ListAllFiles($ );

&Main;


sub Main() {
	open(LOG_FILE, ">log.txt");
	select(LOG_FILE);
	
	my @files = sort &ListAllFiles($ROOT);
	
	my @xul = grep { /\.xul$/ } @files;
	my @js = grep { /\.js$/ } @files;
	my @dtd = grep { /\.dtd$/ } @files;
	my @prop = grep { /\.properties$/ } @files;
	
	CheckDTDVersusXUL(\@dtd, \@xul);
	CheckPrefsVsXULAndJS(\@xul, \@js);
	CheckPropertyStringsVsJS(\@prop, \@js);

	close(LOG_FILE);
}

sub CheckPropertyStringsVsJS($$ ) {
	my $propRef = shift @_;
	my $jsRef = shift @_;

	my %prop = ();
	
	foreach (@$propRef) {
		&ListPropertyStrings(\%prop, $_);
	}
	
	my %propKey = ();
	
	foreach ($STRING_KEYS_FILE) {
		&CheckPropertyStrings(\%prop, \%propKey, $_);
	}
	
	foreach (sort keys %prop) {
		if ($prop{$_} == 0) {
			print "<< property = $_\n";
			print STDERR "property = $_\n";
		}
	}
	
	foreach (@$jsRef) {
		&CheckPropertyStringKeys(\%propKey, $_);
	}
	
	foreach (sort keys %propKey) {
		if ($propKey{$_} == 0) {
			print "<< propKey = $_\n";
			print STDERR "propKey = $_\n";
		}
		else {
			print "|| propKey = $_\n";
		}
	}
	
	1;
}


sub CheckPropertyStringKeys($$ ) {
	my $propKeyRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file") || return;
	my @rows = <FILE1>;
	close(FILE1);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$propKeyRef) {
		print ">> key($key) = ";

		my $x = quotemeta($key);
	
		if ($content =~ /\(\s*org.mozdev.popmungo.stringKeys\.$x\s*[\,\)]/) {
			${$propKeyRef}{$key}++;
			print "true\n";
		}
		elsif ($content =~ /\=\s*org.mozdev.popmungo.stringKeys\.$x[\.\;]/) {
			${$propKeyRef}{$key}++;
			print "true\n";
		}
		else {
			print "false\n";
		}
	}
	
	1;
}

 
sub CheckPropertyStrings($$$ ) {
	my $propRef = shift @_;
	my $propKeyRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file") || return;
	my @rows = <FILE1>;
	close(FILE1);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$propRef) {
		print ">> key($key) = ";

		my $x = quotemeta($key);
	
		if ($content =~ /(\w+)\s*\:\s*([\"\'])$x$2/) {
			${$propKeyRef}{$1} = 0;
			${$propRef}{$key}++;
			print "true\n";
		}
		else {
			print "false\n";
		}
	}
	
	1;
}

 
sub ListPropertyStrings($$ ) {
	my $propRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file");
	my @rows = <FILE1>;
	close(FILE1);
	
	foreach my $row (@rows) {
		# x=y
		if ($row =~ /^\s*(\S+?)\s*\=/i) {
			print ">> prop = $1\n";
			${$propRef}{$1} = 0;
		}
	}
	
	1;
}


sub CheckPrefsVsXULAndJS($$ ) {
	my $xulRef = shift @_;
	my $jsRef = shift @_;

	my %pref = ();
	
	foreach ($PREFS_FILE) {
		&ListPrefs(\%pref, $_);
	}
	
	my $xulPrefRef = {%pref}; 
	
	foreach (@$xulRef) {
		&CheckXULPrefs($xulPrefRef, $_);
	}
	
	foreach (sort keys %$xulPrefRef) {
		if ($$xulPrefRef{$_} == 0) {
			print "<< xulPref = $_\n";
			print STDERR "xulPref = $_\n";
		}
	}
	
	my %prefKey = ();
	
	foreach ($PREF_KEYS_FILE) {
		&CheckJSPrefs(\%pref, \%prefKey, $_);
	}
	
	foreach (sort keys %pref) {
		if ($pref{$_} == 0) {
			print "<< pref = $_\n";
			print STDERR "pref = $_\n";
		}
	}
	
	foreach (@$jsRef) {
		&CheckPrefKeys(\%prefKey, $_);
	}
	
	foreach (sort keys %prefKey) {
		if ($prefKey{$_} == 0) {
			print "<< prefKey = $_\n";
			print STDERR "prefKey = $_\n";
		}
		else {
			print "|| prefKey = $_\n";
		}
	}
	
	1;
}


sub ListPrefs($$ ) {
	my $prefRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(LIST_PREFS_FILES, "<$file");
	my @rows = <LIST_PREFS_FILES>;
	close(LIST_PREFS_FILES);
	
	foreach my $row (@rows) {
		# pref("extensions.popmungo.alertOnError", false);
		if ($row =~ /^\s*pref\(\"(.*?)\"/) {
			print ">> pref = $1\n";
			${$prefRef}{$1} = 0;
		}
	}
	
	1;
}


sub CheckXULPrefs($$ ) {
	my $prefRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file") || return;
	my @rows = <FILE1>;
	close(FILE1);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$prefRef) {
		print ">> key($key) = ";

		my $x = quotemeta($key);
	
		if ($content =~ /name\=([\"\'])$x$1/) {
			print "true\n";

			while ($content =~ s/name\=([\"\'])$x$1//) {
				${$prefRef}{$key}++;
			}
		}
		else {
			print "false\n";
		}
	}
	
	1;
}


sub CheckJSPrefs($$$ ) {
	my $prefRef = shift @_;
	my $prefKeyRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file") || return;
	my @rows = <FILE1>;
	close(FILE1);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$prefRef) {
		print ">> key($key) = ";

		my $x = $key;
		$x =~ s/^extensions\.popmungo\.//;
		$x =~ s/\d+/<n>/g;
		my $x = quotemeta($x);
	
		if ($content =~ /(\w+)\s*\:\s*([\"\'])$x$2/) {
			${$prefKeyRef}{$1} = 0;
			${$prefRef}{$key}++;
			print "true\n";
		}
		else {
			print "false\n";
		}
	}
	
	1;
}

 
sub CheckPrefKeys($$ ) {
	my $prefKeyRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(FILE1, "<$file") || return;
	my @rows = <FILE1>;
	close(FILE1);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$prefKeyRef) {
		print ">> key($key) = ";

		my $x = quotemeta($key);
	
		if ($content =~ /\(\s*org.mozdev.popmungo.prefKeys\.$x\s*[\,\)]/) {
			${$prefKeyRef}{$key}++;
			print "true\n";
		}
		elsif ($content =~ /\=\s*org.mozdev.popmungo.prefKeys\.$x[\.\;]/) {
			${$prefKeyRef}{$key}++;
			print "true\n";
		}
		else {
			print "false\n";
		}
	}
	
	1;
}

 
sub CheckDTDVersusXUL($$ ) {
	my $dtd = shift @_;
	my $xul = shift @_;

	my %dtd = ();
	
	foreach (@$dtd) {
		ListEntities(\%dtd, $_);
	}
	
	foreach (@$xul) {
		CheckEntities(\%dtd, $_);
	}
	
	foreach (sort keys %dtd) {
		if ($dtd{$_} == 0) {
			print "<< dtd = $_\n";
			print STDERR "dtd = $_\n";
		}
	}
	
	1;
}


sub CheckEntities($$ ) {
	my $dtdRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(CHECK_ENTITIES_FILE, "<$file") || return;
	my @rows = <CHECK_ENTITIES_FILE>;
	close(CHECK_ENTITIES_FILE);

	my $content = join('', @rows);
	
	foreach my $key (sort keys %$dtdRef) {
		print ">> key($key) = ";

		my $x = quotemeta($key);

		if ($content =~ /\&$x\;/) {
			print "true\n";

			while ($content =~ s/\&$x\;//) {
				${$dtdRef}{$key}++;
			}
		}
		else {
			print "false\n";
		}
	}
	
	1;
}


sub ListEntities($$ ) {
	my $dtdRef = shift @_;
	my $file = shift @_;
	
	print ">> file = $file\n";
	
	open(LIST_ENTITIES_FILE, "<$file");
	my @rows = <LIST_ENTITIES_FILE>;
	close(LIST_ENTITIES_FILE);
	
	foreach my $row (@rows) {
		# <!ENTITY popmungo.interaction.15.label "Insult">
		if ($row =~ /\<\!ENTITY\s(.*?)\s\"(.*?)\"\>/) {
			print ">> entity = $1\n";
			${$dtdRef}{$1} = 0;
		}
	}
	
	1;
}


sub ListAllFiles($ ) {
	my $dir = shift @_;
	
	opendir(LIST_ALL_FILES_DIR, $dir);
	my @entries = readdir(LIST_ALL_FILES_DIR);
	closedir(LIST_ALL_FILES_DIR);
	
	my @files = ();

	for my $entry (@entries) {
		next if ($entry =~ /^\.\.?$/);
		next if ($entry eq "CVS");
		
		my $fullname = "$dir/$entry";
		
		if (-d $fullname) {
			push(@files, &ListAllFiles($fullname));
		}
		else {
			push(@files, $fullname);
		}
	}
	
	@files;
}
